<?php

namespace app\common\service\around;

use api\channel\jutuike\AroundUnion;
use app\common\service\order\CouponOrderService;
use app\event\SupplierCreateOrder;
use app\event\SupplierNotifyFail;
use app\model\CouponOrder;
use app\model\JtkGoods;
use app\model\JtkGoodsShop;
use app\model\JtkLocation;
use Carbon\Carbon;
use think\facade\Db;
use think\facade\Log;
use think\helper\Arr;

/**
 * 聚推客周边游
 */
class JtkAroundService
{
    private static $instance;

    const CODE_FAIL = 0; // 失败
    const CODE_SUCCESS = 1; // 成功

    const PRODUCT_UPDATE_HOUR = 24; // 商品更新时间 单位小时 默认24小时更新一次

    const JUTUIKE_GOODS_INFO = 'jutuikeGoodsInfo'; // 聚推客商品信息key
    const ORDER_NOTIFY_SEND = 'orderNotifySend'; // 聚推客发码回调key
    const ORDER_NOTIFY_REFUND = 'orderNotifyRefund'; // 聚推客退款回调key
    const ORDER_NOTIFY_CHECK = 'orderNotifyCheck'; // 聚推客核销回调key
    const ORDER_REFUND_ORDER_RES = 'refundOrderRes'; // 聚推客核销产品退款key
    const ORDER_REFUND_ORDER_RES_FAIL = 'refundOrderResFail'; // 聚推客核销产品退款失败key

    // 创建一个用来实例化对象的方法
    public static function getInstance(){
        if (!isset(self::$instance) || (self::$instance === NULL)) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    /**
     * 前端 站点列表根据字母排
     * @return array
     */
    public function getLocationListWord() {
        $dataList = JtkLocation::locationAll();
        $result = [];
        /** @var JtkLocation $item */
        foreach ($dataList as $item) {
            $firstWord = $item->first_word;
            if (!isset($result[$firstWord]['firstWord'])) {
                $result[$firstWord]['firstWord'] = $firstWord;
            }
            $result[$firstWord]['items'][] = $item;
        }
        sort($result);
        return $result;
    }



    /**
     * H5调用的 写死的站点分类
     * @return array[]
     */
    public function getProductCategory() {
        $attr = (new JtkGoods())->getCategoryAttr();
        array_unshift($attr, '全部');
        return $attr;
    }


    /**
     * 聚推客--站点分类
     * @return array|false|mixed
     */
    public function getProductCategoryJtk($params) {
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->queryProductCategory($params);
        if (isset($res['code']) && $res['code'] == self::CODE_FAIL) {
            echo '聚推客站点下的分类信息不存在' . PHP_EOL;
            return false;
        }
//        $dataList = $res['data'];
//        $tree = [];  // 格式化好的数组
//        $dataIdTemp = $dataList ? array_column($dataList, null, 'id') : [];
//        foreach ($dataList as $item) {
//            $id = $item['id'];
//            $item['parentId'] != 0 ? $dataIdTemp[$item['parentId']]['children'][] = &$dataIdTemp[$id] : $tree[] = &$dataIdTemp[$id];
//        }
//        echo '<pre>';
//        var_dump($tree);
//        die();
//        return $tree;

//        halt($res['data']);
        $dataList = Collect($res['data'])->where('id', '636');
//        $dataList = Collect($res['data'])->where('parentId', '0');
//        $dataList = Collect($res['data'])->where('parentId', '270');
        halt($dataList);

        return $res['data'] ?? [];
    }

    /**
     * 递归 获取聚推客周边游商品
     * @param $locationId 站点编号
     * @param $pageIndex 页数
     * @return array
     * @throws \Exception
     */
    protected function recursionPullProduct($locationId, $pageIndex = 1) {
        $result = ['status' => false, 'msg' => '商品读取失败，请联系管理员！'];
        $params = [
            'locationId' => $locationId,
//            'locationIdList' => $locationId,
            'pageIndex' => $pageIndex,
            'pageSize' => 20, // 默认取20
        ];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->queryProductList($params);
        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }
        $dataList = $res['data'] ?? [];
        if (empty($dataList)) {
            $result = ['status' => true, 'msg' => '商品读取成功,暂无相关数据'];
            return $result;
        }

        $data = $dataList['data'] ?? [];
        // 写入数据
        (new JtkGoods())->batchSaveDataJtk($data);

        $pageCount = $dataList['pageCount'] ?? 0; // 总的页数
        if ($pageCount > $pageIndex) {
            $pageIndex = $pageIndex + 1;
            $this->recursionPullProduct($locationId, $pageIndex);
        }
        $result = ['status' => true, 'msg' => '商品读取成功1'];
        return $result;
    }

    /**
     * 获取商品 聚推客周边游 商品信息 拉取并且保存到本地
     * 先从数据库差商品是否存在或者超过24小时 不存在 拉聚推客的商品且存到本地，
     * 当前数据库获取
     * @param $params
     * @return array
     */
    protected function pullProductByJtk($params) {
        $result = ['status' => false, 'msg' => '商品读取失败，请联系管理员！'];

        $locationId = $params['location_id'];

        $model = JtkGoods::query()
            ->where('location_id', $locationId)
            ->where('created_at','>',Carbon::now()->startOfDay()->toDateTimeString())
            ->order('id asc')
            ->find();
        // 24小时 数据更新一次 将产品信息同步到渠道商持久存储
        if ($model)  {
            $result = ['status' => true, 'msg' => '商品读取成功'];
            return $result;
        }


        Db::startTrans();
        try {
            // 先清除当前站点的旧数据
            JtkGoods::query()->where('location_id', $locationId)->delete(true); // 这种写法软删除无效
            JtkGoodsShop::query()->where('location_id', $locationId)->delete(true);
            // 这种写法软删除无效 直接删除
//            JtkGoods::destroy(function($query) use ($locationId) {
//                $query->where('location_id', $locationId);
//            });
//
//            JtkGoodsShop::destroy(function($query) use ($locationId) {
//                $query->where('location_id', $locationId);
//            });

            // 递归取拉聚推客的数据
            $result = $this->recursionPullProduct($locationId);
            if ($result['status']) {
                Db::commit();
            } else {
                Db::rollback();
            }
            return $result;
        } catch (\Exception $e) {
            Db::rollback();

            $result['msg'] = $e->getMessage();
            return $result;
        }
        return $result;
    }

    // 聚推客 测试接口
    public function productListJtk($params) {
        $result = ['status' => false, 'msg' => '商品读取失败，请联系管理员！'];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->queryProductList($params);

        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }

        // 读取商品列表
        $dataList = $res['data'] ?? [];
        $result = ['status' => true, 'msg' => '商品读取成功', 'data' => $dataList ];
        return $result;
    }

    /**
     * 聚推客退款测试
     * @param $params
     * @return array
     */
    public function refundOrderJtk($params) {
        $result = ['status' => false, 'msg' => '退款失败，请联系管理员！'];
        $data = [
            'thirdPartyOrderNo' => $params['order_id']
        ];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->refundOrder($data);
        Log::info('聚推客周边游申请退款' . json_encode($res));
        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }

        $result = ['status' => true, 'msg' => '退款已申请', 'data' => $result['data'] ];
        return $result;
    }

    /**
     * 聚推客--商品列表
     * @param $params
     * @return array
     */
    public function productList($params) {
        $locationId = $params['location_id'] ?? 0;
        $cityName = $params['city_name'] ?? '';
        if (empty($locationId) && !empty($cityName)) {
            $params['location_id'] = JtkLocation::locationIdByCityName($cityName);
//            $locationId = $params['location_id'];
        }
        if (!isset($params['location_id'])) {
            $params['location_id'] = 0;
        }
        $categoryName = $params['category_name'] ?? '全部';
//        if (trim($categoryName) == '全部' && !empty($locationId)) {
            $result = $this->pullProductByJtk($params);
            if ($result['status'] == false) {
                Log::info('聚推客拉取商品返回信息-'. json_encode($result, JSON_UNESCAPED_UNICODE));
            }
//        }

        // 读取商品列表
        $data = (new JtkGoods())->dataList($params);

        $result = ['status' => true, 'msg' => '商品读取成功', 'data' => $data ];
        return $result;
    }

    /**
     * 商品基本信息
     * @param $params
     * @return array
     */
    public function productInfo($params) {
        $result = ['status' => false, 'msg' => '商品基本信息读取失败，请联系管理员！'];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->queryProductByCondition($params);
        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }
        $dataList = $res['data'] ?? [];
        $latitude = $params['latitude'] ?? '';
        $longitude = $params['longitude'] ?? '';
        if (isset($dataList['shops']) && !empty($latitude) && !empty($longitude)) {
            foreach ($dataList['shops'] as &$item) {
                $item['dis'] = latLngMapApiDistance($latitude, $longitude, $item['latitude'], $item['longitude'], true);
            }
            $shopDisSort = Collect($dataList['shops'])->order('dis')->toArray();
            $dataList['shops'] = array_values($shopDisSort);
        }
        if (isset($dataList['title'])) {
            $dataList['title'] = str_replace( 'null', '', $dataList['title']);
        }
        $result = ['status' => true, 'msg' => '商品基本信息读取成功', 'data' => $dataList ];
        return $result;
    }

    /**
     * 商品图文详情v1
     * 查询产品图文详情(文案)
     * @param $params
     * @return array
     */
    public function productDetailV1($params) {
        $result = ['status' => false, 'msg' => '商品图文详情读取失败，请联系管理员！'];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->productDetailV1($params);
        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }
        $dataList = $res['data'] ?? [];
        $result = ['status' => true, 'msg' => '商品图文详情读取成功', 'data' => $dataList ];
        return $result;
    }

    /**
     * 商品图文详情v1
     * 查询产品图文详情(文案)
     * @param $params
     * @return array
     */
    public function productDetailV2($params) {
        $result = ['status' => false, 'msg' => '商品图文详情读取失败，请联系管理员！'];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->productDetailV2($params);
        $code = $res['code'] ?? self::CODE_FAIL;
        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            return $result;
        }
        $dataList = $res['data'] ?? [];
        $result = ['status' => true, 'msg' => '商品图文详情读取成功', 'data' => $dataList ];
        return $result;
    }

    /**
     * 1、创建订单 推送给聚推客那边
     * 2、推送成功后数据需要保存 CouponOrder 表
     * @param CouponOrder $couponOrder
     * @return array|void
     */
    public function createOrder(CouponOrder $couponOrder) {
        $result = ['status' => false, 'msg' => '下单失败'];
        if (empty($couponOrder)) {
            $result['msg'] = '下单失败，订单不存在';
            return $result;
        }
        $params = [
            'thirdPartyOrderNo' => $couponOrder->order_id,
        ];

        //
        if (isProd() || isTesting()) { // 正式环境执行
            $aroundUnion =  new AroundUnion();
            $res = $aroundUnion->createOrder($params);
            if (empty($res)) {
                Log::info('聚推客周边游下单失败,未响应' . json_encode($result, JSON_UNESCAPED_UNICODE));
                $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_WAIT_CONFIRM;
                $couponOrder->remark = $couponOrder->remark . ' 供应商下单无响应，待确认';
                $couponOrder->save();
                return;
            }
            $code = $res['code'] ?? self::CODE_FAIL;
            if ($code != self::CODE_SUCCESS) {
                $result['msg'] = $res['msg'] ?? $result['msg'];
                Log::info('聚推客周边游下单失败' . json_encode($result, JSON_UNESCAPED_UNICODE));
                event(new SupplierNotifyFail($couponOrder));
                return $result;
            }
        }

        $extData = $couponOrder->ext_data ?? [];
        $extData['createOrderJtkRes'] = $res['data'] ?? [];
        $couponOrder->ext_data = $extData;
        if (isset($res['data']['channelOrderId'])) {
            $couponOrder->supplier_order_sn = $res['data']['channelOrderId'];
        }


        // 创建订单
        event(new SupplierCreateOrder($couponOrder));

//        $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_SUBMIT;
//        $couponOrder->status = CouponOrder::C_STATUS_SUBMIT;
//        $couponOrder->save();
        $result = ['status' => true, 'msg' => '下单成功'];
        return $result;
    }

    /**
     * 周边游申请退款
     * @param CouponOrder $couponOrder
     * @return array
     */
    public function refundOrder(CouponOrder $couponOrder) {
        $result = ['status' => false, 'msg' => '操作失败'];
        if ($couponOrder->serv_type != PRODUCT_AROUND_SHOP_SERV
            && $couponOrder->type != CouponOrder::TYPE_COUPON_SELF_EMPLOYED) {
            $result['msg'] = '该订单非周边游,不可申请退款！请联系客服';
            return $result;
        }

        if ($couponOrder->refund_status != CouponOrder::C_REFUND_STATUS_NO) { // 未退款的才能退款
            $result['msg'] = '该订单退款中或者已退款，请联系客服';
            return $result;
        }
        if ($couponOrder->pay_status == CouponOrder::C_PAY_STATUS_NO) { // 已支付的订单才能退款
            $result['msg'] = '该订单未支付，不能申请退款';
            return $result;
        }
        if ($couponOrder->supplier_status == CouponOrder::SUPPLIER_STATUS_REFUNDING) {
            $result['msg'] = '退款中，请稍后再来查看';
            return $result;
        }

        if ($couponOrder->status == CouponOrder::C_STATUS_RECHARGE_SUCCESS
            && $couponOrder->supplier_status == CouponOrder::SUPPLIER_STATUS_SUCCESS) {
            $result['msg'] = '订单已核销，不能申请退款';
            return $result;
        }


        $extData = $couponOrder->ext_data ?? [];
        if (empty($extData)) {
            $result['msg'] = '订单数据异常，请联系客服';
            return $result;
        }

        // 订单还没有发码回调，不能退款
        $orderNotifySend = $extData[self::ORDER_NOTIFY_SEND] ?? [];
        if (empty($orderNotifySend)) {
            $result['msg'] = '订单还在处理中，请稍后再操作';
            return $result;
        }

        $refundOrderRes = $extData[self::ORDER_REFUND_ORDER_RES] ?? [];
        if ($refundOrderRes) {
            $result['msg'] = '只能申请一次退款，有疑问请联系客服';
            return $result;
        }

//        $orderNotifyCheck = $extData[JtkAroundService::ORDER_NOTIFY_CHECK] ?? [];
//        if ($orderNotifyCheck) { // 商品核销的不能在退款
//            $result['msg'] = '订单已核销，不能申请退款';
//            return $result;
//        }

        $jutuikeGoodsInfo = $extData[self::JUTUIKE_GOODS_INFO] ?? [];
        if (empty($jutuikeGoodsInfo)) {
            $result['msg'] = '订单的商品数据异常，请联系客服';
            return $result;
        }

        // 过期的商品不能在退款 validEndDate
        if (isset($jutuikeGoodsInfo['validEndDate']) && msectime() >= $jutuikeGoodsInfo['validEndDate']) {
            $result['msg'] = '订单的商品已过期，不能申请退款，请联系客服';
            return $result;
        }

        $params = [
            'thirdPartyOrderNo' => $couponOrder->order_id
        ];
        $aroundUnion =  new AroundUnion();
        $res = $aroundUnion->refundOrder($params);
        Log::info('聚推客周边游申请退款' . json_encode($result, JSON_UNESCAPED_UNICODE));
        if (empty($res)) {
            $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_WAIT_CONFIRM;
            $couponOrder->remark = $couponOrder->remark . ' 供应商申请退款无响应，待确认';
            $result['msg'] = '订单申请退款异常，请联系客服';
            $extData[self::ORDER_REFUND_ORDER_RES_FAIL] = $result;
            $couponOrder->ext_data = $extData;
            $couponOrder->save();
            return $result;

        }
        $code = $res['code'] ?? self::CODE_FAIL;

        if ($code != self::CODE_SUCCESS) {
            $result['msg'] = $res['msg'] ?? $result['msg'];
            $extData[self::ORDER_REFUND_ORDER_RES_FAIL] = $result;
            $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_WAIT_CONFIRM;
            $couponOrder->remark = $couponOrder->remark . ' 退款失败：' . $result['msg'];
            $couponOrder->ext_data = $extData;
            $couponOrder->save();
            return $result;
        }

        $extData[self::ORDER_REFUND_ORDER_RES] = $res['data'] ?? [];
        $couponOrder->ext_data = $extData;
        $couponOrder->supplier_status = CouponOrder::SUPPLIER_STATUS_REFUNDING;
        $couponOrder->save();

        $result = ['status' => true, 'msg' => '已提交退款请求，退款成功后金额将原路退回~'];
        return $result;
    }

    /**
     * 周边游下单测试
     * @return CouponOrder|false|\think\db\Query
     * @throws \think\Exception
     */
    public function createTest() {
        $locationId = JtkLocation::locationIdByCityName('厦门');
        $goodParams = [
            'pageIndex' => 1,
            'pageSize' => 1,
            'locationId' => $locationId,
        ];

        $result = $this->productListJtk($goodParams);
        $data = $result['data']['data'];
        if (empty($data)) {
            return false;
        }
        $goodsInfo = Collect($data)->first();
        $itemFirst = Collect($goodsInfo['items'])->first();
        if (empty($itemFirst)) {
            return false;
        }

        $couponOrder = (new CouponOrderService())
            ->create([
                'productId' => $goodsInfo['id'], // 产品ID
                'locationId' => $goodsInfo['locationId'], // 站点
                'itemId' => $itemFirst['id'], // 套餐ID
                'customerName' => 'lee', // 客户姓名
                'customerPhoneNumber' => 18205918625, // 客户电话
                'quantity' => 1, // 数量
                'itemSalePrice' => fen2yuan($itemFirst['salePrice']), // 套餐单价
                'serv_type' => PRODUCT_AROUND_SHOP_SERV,
            ]);

        return $couponOrder;
    }
}